import React, { useState, useCallback, useEffect } from "react";
import { useLocalStorageState } from "ahooks";
import { Table, Checkbox, message, Button, Space } from "antd";
import { CommonModal } from "@/views/components/CommonModal";
import { useUpdateEffect } from "ahooks";
import { cloneDeep } from "lodash";
import { SortableContainer, SortableElement, SortableHandle } from "react-sortable-hoc";
import IconFont from "@/components/IconFont";
import { SwapOutlined, VerticalAlignTopOutlined, VerticalAlignBottomOutlined } from "@ant-design/icons";
import Style from "./index.module.less";
import InvertButton from "./InvertButton";

const rowKey = "code";
const checkSelection = tableData => {
	const checkableTable = tableData.filter(e => !e.lock);
	const checkedCols = checkableTable.filter(e => e.checked);
	const checkAll = checkedCols.length === checkableTable.length;
	const indeterminate = checkedCols.length > 0 && checkedCols.length < checkableTable.length;
	const empty = checkedCols.length === 0;
	return {
		checkAll,
		indeterminate,
		empty
	};
};
export default React.memo(
	({ tableKey, defaultColumns, columns, saveRemoteData, initColsSetting, title = "列表字段设置", open, setOpen }) => {
		const ComponentName = "ColsSetting";
		if (!tableKey) {
			return <>{`${ComponentName},需要提供 tableKey`}</>;
		}

		useEffect(() => {
			if (tableKey) initColsSetting();
		}, [tableKey]);

		const [visible, setVisible] = useState(false);

		const [tableData, setTableData] = useState([]);
		useEffect(() => {
			setTableData(
				cloneDeep(columns).map(e => {
					let name = typeof e.name === "function" ? e.name() : e.name;
					if (typeof name !== "string") {
						name = "请为此列配置提供字符串格式的name属性，render可以使用title";
						console.error(e, tableKey + name);
					}

					if (!e.code) {
						name = "请为此列配置提供code";
						console.error(e, tableKey + name);
					}
					return { ...e, name };
				})
			);
		}, [columns]);

		const handleModalOk = useCallback(() => {
			const { empty } = checkSelection(tableData);
			if (empty) {
				message.warning("请至少勾选一项");
				return;
			}
			saveRemoteData(tableData);
			hideModal();
		}, [saveRemoteData, setVisible, tableData]);

		const onSortEnd = ({ oldIndex, newIndex }) => {
			if (oldIndex !== newIndex) {
				const newTableData = cloneDeep(tableData);
				// removing the item
				const oldItem = cloneDeep(tableData[oldIndex]);
				newTableData.splice(oldIndex, 1);
				// pushing in the new position
				newTableData.splice(newIndex, 0, oldItem);

				setTableData(newTableData);
			}
		};
		/**
		 * action: lock | unlock
		 */
		const onMove = useCallback(
			(record, index, action) => {
				//
				const newTableData = cloneDeep(tableData);
				// removing the item
				newTableData.splice(index, 1);

				if (action == "lock") {
					// 如果锁定的是下面的字段保存后该字段会自动上移到上面其他锁定字段的下面及未锁定字段的前面，并且锁定的字段不管是否勾选显示都代表显
					const i = newTableData.findIndex(e => e.lock !== true);
					// pushing in the new position
					record.lock = true;
					record.checked = true;
					newTableData.splice(i, 0, cloneDeep(record));
				} else {
					const i = newTableData.findIndex((e, i) => i >= index && e.lock !== true);
					const lastUnlockIndex = i > -1 ? i : tableData.length - 1;
					record.lock = false;
					newTableData.splice(lastUnlockIndex, 0, cloneDeep(record));
				}
				setTableData(newTableData);
			},
			[tableData]
		);
		const SortableItem = SortableElement(props => <tr {...props} />);
		const SortableBody = SortableContainer(props => <tbody {...props} />);
		const DisabledDragHandle = () => <IconFont type="icona-lujing121" />;
		const DragHandle = SortableHandle(() => <IconFont type="icona-lujing121" style={{ cursor: "move" }} />);
		const DraggableContainer = props => (
			<SortableBody useDragHandle disableAutoscroll helperClass="row-dragging" onSortEnd={onSortEnd} {...props} />
		);
		const DraggableBodyRow = ({ className, style, ...restProps }) => {
			// function findIndex base on Table rowKey props and should always be a right array index
			const index = tableData.findIndex(x => x[rowKey] === restProps["data-row-key"]);
			const record = tableData[index];
			const disabledMove =
				record && (record.code === "index" || record.code === "action" || record.name === "操作" || record.name === "序号");
			if (disabledMove) return <tr index={index} {...restProps} />;
			return <SortableItem index={index} {...restProps} />;
		};

		const onCheckSimpleChange = useCallback(
			(e, row) => {
				const flag = e.target.checked;
				const v = row[rowKey];
				const __tableData = tableData.map(e => {
					const checked = e[rowKey] === v ? flag : e.checked;

					return {
						...e,
						checked
					};
				});
				setTableData(cloneDeep(__tableData));
			},
			[tableData, setTableData]
		);
		const AllCheckBox = ({ tableData, setTableData, children, ...restProps }) => {
			const { checkAll, indeterminate, empty } = checkSelection(tableData);

			function onCheckAllChange(e) {
				const flag = e.target.checked;
				const __tableData = tableData.map(e => {
					const checked = e.lock ? true : flag;
					return {
						...e,
						checked
					};
				});
				setTableData(cloneDeep(__tableData));
			}
			return (
				<Checkbox indeterminate={indeterminate} checked={checkAll} onChange={onCheckAllChange} {...restProps}>
					{children}
				</Checkbox>
			);
		};
		const handleInvert = () => {
			setTableData(pre => {
				pre.forEach(e => {
					if (e.lock != true) e.checked = !e.checked;
				});

				return cloneDeep(pre);
			});
		};

		function showModal() {
			setOpen ? setOpen(true) : setVisible(true);
		}
		function hideModal() {
			setOpen ? setOpen(false) : setVisible(false);
		}
		useEffect(() => {
			setVisible(open);
		}, [open]);

		return (
			<>
				{!setOpen && (
					<Button
						type="text"
						onClick={() => {
							showModal();
						}}
					>
						<IconFont type="icona-lujing12" />
						列表设置
					</Button>
				)}

				<CommonModal
					width={528}
					title={{ title }}
					open={visible}
					onCancel={e => {
						setTableData(cloneDeep(columns));
						hideModal();
					}}
					onOk={e => {
						handleModalOk(e);
					}}
					footer={
						<>
							<Button
								onClick={e => {
									setTableData(cloneDeep(columns));
									hideModal();
								}}
							>
								取消
							</Button>
							<Button
								onClick={e => {
									setTableData(cloneDeep(defaultColumns));
								}}
							>
								恢复默认设置
							</Button>
							<Button
								type="primary"
								onClick={e => {
									handleModalOk(e);
								}}
							>
								保存
							</Button>
						</>
					}
				>
					<div className={Style.header_txt}>
						<p>选择哪个字段，订单列表就会显示哪个字段。锁定的字段会移动到前面并且固定。</p>
						<span>(上下可拖动字段排序)</span>
					</div>
					<Table
						bordered
						rowKey="code"
						components={{
							body: {
								wrapper: DraggableContainer,
								row: DraggableBodyRow
							}
						}}
						columns={[
							{
								title: <span className={Style.btn_text}>筛选字段</span>,
								dataIndex: "name"
							},
							{
								title: (
									<div className="flex">
										<span className={Style.btn_text}>是否显示</span>
										<AllCheckBox tableData={tableData} setTableData={setTableData} className="ml8 mr8">
											<span className={Style.btn_text}>全选</span>
										</AllCheckBox>
										<InvertButton onClick={handleInvert} />
									</div>
								),
								render: (text, record, index) => {
									const disabledMove =
										record &&
										(record.code === "index" || record.code === "action" || record.name === "操作" || record.name === "序号");
									if (disabledMove) {
										return (
											<Space className={Style.action + " justify-center"}>
												<Checkbox disabled checked={record.checked} />
												<div className={Style.hover}></div>
											</Space>
										);
									} else {
										return (
											<Space className={Style.action + " justify-center"}>
												<Checkbox
													disabled={record.lock}
													checked={record.checked}
													onChange={e => onCheckSimpleChange(e, record)}
												/>
												<div className={Style.hover}>
													{record.lock ? <DisabledDragHandle /> : <DragHandle />}
													{!record.lock && <IconFont type="icona-lujing112" onClick={() => onMove(record, index, "lock")} />}
													{record.lock && <IconFont type="icona-lujing14" onClick={() => onMove(record, index, "unlock")} />}
												</div>
											</Space>
										);
									}
								},
								width: 240
							}
						]}
						dataSource={tableData}
						pagination={false}
						scroll={{
							y: 500
						}}
					/>
				</CommonModal>
			</>
		);
	}
);
